(function() {
	var io;
	var room = [];
	var locked_object = [];
	var users = [];
	var idle = 0;
	
	function findLockedData(roomId)
	{
		for(var i=0;i<locked_object.length;i++)
		{
			if(locked_object[i].roomId == roomId)
			{
				return locked_object[i];
			}
		}
		return false;
	}
	
	io = require('socket.io').listen(4080);
		 // io.set('transports', [
	   // 'xhr-polling',
	  // ]);
	  io.set('log level',0);
	  // io.set('heartbeat timeout',10);
	  // io.set('heartbeat interval',2);
	  // io.set('close timeout',2);
	  io.set('transports', [
	   'xhr-polling',
	  ]);
	  
	// io.set('close timeout', 15);
	io.sockets.on('connection', function(socket) {
		var lastUserData=[];
		
		io.sockets.socket(socket.id).emit('connected');
		socket.on('cm_auth', function(data){
			if(!room[data.roomid]){
				room[data.roomid] = [];
				room[data.roomid][data.page] = [];
			} else {
				if(!room[data.roomid][data.page]){
					room[data.roomid][data.page] = [];
				} 
			}
			
			if(!findLockedData(data.roomid)){
				var lockData = {
					roomId:data.roomid,
					lockedObject:[],
				};
				locked_object.push(lockData);
			} 
			var userObject = {
				username:data.username,
				user_id:data.userid,
				room:data.roomid,
				socket_id:socket.id,
			};
			users.push(userObject);
			
			socket.username = data.username;
			socket.userid = data.userid;
			socket.room = data.roomid;
			
			socket.join(socket.room);
			io.sockets.socket(socket.id).emit('sm_auth', {
						socketId:socket.id, 
						lockedInThisPage:findLockedData(data.roomid),
						users:users,
					});
			socket.broadcast.to(socket.room).emit('sm_update_user_data', {
				id: data.id,
				roomid: data.roomid,
				users:users,
			});
		});
		socket.on('cm_background', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_background', {
				id: data.id,
				roomid: data.roomid,
				pageId: data.pageId,
				imageUrl: data.imageUrl,
			});
		});
		socket.on('cm_update_user_data', function(data) {
			idle = 1; 
			var userIndex = -1;
			for(var i=0;i<users.length;i++)
			{
				if(users[i].room == data.roomid && users[i].username == data.username )
				{
					userIndex=i;
					break;
				}
			}
			if(userIndex >= 0)
			{
				users.splice(userIndex,1); 
				socket.emit('sm_update_user_data', {
					id: data.id,
					roomid: data.roomid,
					users:users,
				});
				socket.broadcast.to(socket.room).emit('sm_update_user_data', {
					id: data.id,
					roomid: data.roomid,
					users:users,
				});
			}
			
		});
		socket.on('cm_new', function(data) {
			idle = 1;
			console.log("cm_new "+data.type);
			socket.broadcast.to(socket.room).emit('sm_new', {
				id: data.id,
				roomid: data.roomid,
				pageid:data.pageid,
				object: data.object,
				type:data.type
			});
		});
		socket.on('cm_new_page', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_new_page', {
				id: data.id,
				roomid: data.roomid,
				pageid:data.pageid,
				object: data.object
			});
		});
		socket.on('cm_object_send',function(data){
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_object_send',{
				id : data.id,
				kind : data.kind,
				cmd : data.cmd,
				height : data.height,
				width : data.width,
				object : data.object
			});
		
		});
		socket.on('cm_chat', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_chat', {
				id: data.id,
				roomid: data.roomid,
				object: data.objects
			});
		});
		socket.on('cm_update', function(data) {
			idle = 1;
			if(data.coordinate == undefined)
			{
				data.coordinate={top:-1,left:-1};
			}
			if(data.size == undefined)
			{	
				data.size={width:-1,height:-1};
			}
			socket.broadcast.to(socket.room).emit('sm_update', {
				id: data.id,
				roomid: data.roomid,
				coordinate: data.coordinate,
				objId: data.objId,
				size: data.size,
			});
		});
		socket.on('cm_update_image', function(data) {
			socket.broadcast.to(socket.room).emit('sm_update_image', {
				id: data.id,
				roomid: data.roomid,
				pageid: data.pageid,
				objId: data.objId,
				image_url: data.image_url,
			});
		});	
		socket.on('cm_update_single_object', function(data) {
			socket.broadcast.to(socket.room).emit('sm_update_single_object', data);
		});
	
		socket.on('cm_delete', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_delete', {
				id: data.id,
				roomid: data.roomid,
				deletedId: data.deletedId,
				type:data.type
			});
		})
		socket.on('cm_delete_page', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_delete_page', {
				pageId: data.pageId,
				roomId: data.roomId,
				newArrangement: data.newArrangement,
			});
		});
		socket.on('cm_select_object', function(data) {
			idle = 1;
			socket.emit('sm_select_object', {
				userId: data.userId,
				username: data.username,
				roomId: data.roomId,
				pageId: data.pageId,
				objectId: data.objectId,
			});
			socket.broadcast.to(socket.room).emit('sm_select_object', {
				userId: data.userId,
				username: data.username,
				roomId: data.roomId,
				pageId: data.pageId,
				objectId: data.objectId,
			});
		});
		
		// socket.on('cm_select_active_object', function(data) {
			// socket.emit('sm_select_active_object', {
				// userId: data.userId,
				// username: data.username,
				// roomId: data.roomId,
				// pageId: data.pageId,
				// objectId: data.objectId,
				// zIndex: data.zIndex
			// });
			// socket.broadcast.to(socket.room).emit('sm_select_active_object', {
				// userId: data.userId,
				// username: data.username,
				// roomId: data.roomId,
				// pageId: data.pageId,
				// objectId: data.objectId,
				// zIndex: data.zIndex
			// });
		// });
		
		socket.on('cm_deselect_object', function(data) {
			idle = 1;
			socket.emit('sm_deselect_object', {
				userId: data.userId,
				username: data.username,
				roomId: data.roomId,
				pageId: data.pageId,
				objectId: data.objectId,
				
			});
			socket.broadcast.to(socket.room).emit('sm_deselect_object', {
				userId: data.userId,
				username: data.username,
				roomId: data.roomId,
				pageId: data.pageId,
				objectId: data.objectId,
				
			});
		});
		
		socket.on('cm_move', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_move', {
				id: data.id,
				roomid: data.roomid,
				page: data.page,
				position: {
					top: data.position.top,
					left: data.position.left
				}
			});
		});
		
		socket.on('cm_lock', function(data) {
			var lockedInThisPage = findLockedData(data.roomid);
			var alreadyLocked = false;
			for(var i=0;i<lockedInThisPage.lockedObject.length;i++)
			{
				if(lockedInThisPage.lockedObject[i].pageId == data.pageid &&  lockedInThisPage.lockedObject[i].objectId == data.objectId)
				{
					if(lockedInThisPage.lockedObject[i].lock_status == 4 && data.status == 3)
						alreadyLocked=false;
					else
						alreadyLocked=true;
						
					console.log("consololey log "+alreadyLocked);
					break;
				}
			}
			console.log(alreadyLocked+" cm_locke "+data.status+","+data.objectId);
			if(!alreadyLocked)
			{
				var lockedData = {
					pageId:data.pageid,
					objectId:data.objectId,
					lockerId:data.id,
					username:data.userName,
					lock_status:data.status,
					password:data.password,
				};
				if(data.status == 3){
					//upgrade lock select to lock all
					var spliceIndex=-1;
					for(var i=0;i<lockedInThisPage.lockedObject.length;i++)
					{
						if(lockedInThisPage.lockedObject[i].pageId == data.pageid &&  lockedInThisPage.lockedObject[i].objectId == data.objectId &&  lockedInThisPage.lockedObject[i].lock_status == 4 )
						{
							spliceIndex=i;
							break;
						}
					}
					if(spliceIndex >= 0)
					{
						console.log("Splicing locked objects");
						lockedInThisPage.lockedObject.splice(spliceIndex,1);
					}
				}
				lockedInThisPage.lockedObject.push(lockedData);
				console.log(lockedInThisPage);
				
				
				socket.emit('sm_lock',  {
					id: data.id,
					roomid: data.roomid,
					pageid:data.pageid,
					lockedInThisPage:lockedInThisPage,
				});
				socket.broadcast.to(socket.room).emit('sm_lock', {
					id: data.id,
					roomid: data.roomid,
					pageid:data.pageid,
					lockedInThisPage:lockedInThisPage,
				});
			}
		});
		
		socket.on('cm_unlock', function(data) {
			console.log('cm_unlock');
			var lockedInThisPage = findLockedData(data.roomid);
			var alreadyLocked = false;
			var lockedIndex = -1;
		
			for(var i=0;i<lockedInThisPage.lockedObject.length;i++)
			{
				if(lockedInThisPage.lockedObject[i].pageId == data.pageid &&  lockedInThisPage.lockedObject[i].objectId == data.objectId )
				{
					if(!(lockedInThisPage.lockedObject[i].lock_status == 3 && data.status == 4))
					{
						alreadyLocked=true;
						lockedIndex=i;
						break;
					}
				}
			}
			if(alreadyLocked)
			{
				lockedInThisPage.lockedObject.splice(lockedIndex,1);
				socket.emit('sm_unlock',  {
					id: data.id,
					roomid: data.roomid,
					pageid:data.pageid,
					status:data.status,
					objectid: data.objectId,
					lockedInThisPage:lockedInThisPage, 
				});
				socket.broadcast.to(socket.room).emit('sm_unlock', {
					id: data.id,
					roomid: data.roomid,
					pageid:data.pageid,
					status:data.status,
					objectid: data.objectId,
					lockedInThisPage:lockedInThisPage,
				});
			}
		});


		
		socket.on('cm_resize', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_resize', {
				id: data.id,
				roomid: data.roomid,
				page: data.page,
				size: {
					width: data.size.width,
					height: data.size.height
				}
			});
		});
		socket.on('cm_transfer_lock', function(data) {
			socket.emit('sm_transfer_lock',findLockedData(data.roomid));
		});
	
		socket.on('cm_copy', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('cm_copy', {
				id: data.id,
				roomid: data.roomid,
				page: data.page,
				size: {
					width: data.size.width,
					height: data.size.height
				}
			});
		});
	
		socket.on('cm_z_index', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_z_index', {
				roomid: data.roomId,
				page: data.pageId,
				id: data.userId,
				objectId:data.objectId,
				z_index:data.z_index
			});
		});
		socket.on('cm_quit', function(data) {
			idle = 1;
			socket.broadcast.to(socket.room).emit('sm_quit', {
				roomid: data.roomId,
				id: data.userId,
				username:data.username,
			});
		});
		socket.on('disconnect', function(){ 
			idle = 0;
			socket.leave(socket.room);
			var disconnectedId=-1;
			for(var i=0;i<users.length;i++)
			{
				if(users[i].socket_id == socket.id)
				{
					// console.log("disconnect");
					// console.log(users[i].username);
					// console.log(users);
					disconnectedId=i;
				}
			}
			if(disconnectedId >=0)
			{
				var removed = users.splice(disconnectedId,1); 
					console.log(" ada yang dc,removed");
					console.log(removed[0]);
				socket.broadcast.to(socket.room).emit('sm_user_dc', {
					id: "",
					roomid: socket.room,
					users:users, 
					removed:removed[0], 
				});
			}
			var lockedInThisPage = findLockedData(socket.room);
			
			
			if(lockedInThisPage)
			{
				var lockedIndex = -1;
				var pageidUnlock = 1;
				var statusUnlock = 4;
				var objectIdUnlock = 0;
				var roomIdUnlock = socket.room;
				for(var i=0;i<lockedInThisPage.lockedObject.length;i++)
				{
					
					if(parseInt(lockedInThisPage.lockedObject[i].lock_status) == 4 &&  lockedInThisPage.lockedObject[i].username == socket.username )
					{
						lockedIndex=i;
						pageidUnlock = lockedInThisPage.lockedObject[i].pageId;
						statusUnlock = lockedInThisPage.lockedObject[i].lock_status;
						objectIdUnlock = lockedInThisPage.lockedObject[i].objectId;
						break;
					}
				} 
				if(lockedIndex >= 0)
				{
					lockedInThisPage.lockedObject.splice(lockedIndex,1);
					socket.emit('sm_unlock',  {
						id: "",
						roomid: roomIdUnlock,
						pageid:pageidUnlock,
						status:statusUnlock,
						objectid: objectIdUnlock,
						lockedInThisPage:lockedInThisPage, 
					});
					
					socket.broadcast.to(socket.room).emit('sm_unlock', {
						id: "",
						roomid: roomIdUnlock,
						pageid:pageidUnlock,
						status:statusUnlock,
						objectid: objectIdUnlock,
						lockedInThisPage:lockedInThisPage, 
					});
				}
			}
		});
		 

	});
}).call(this);
